﻿// Author: Radu-Mihail
// Project: PageCrawlQueue, File: BFSQueue.cs
// Namespace: PageCrawlQueue, Class: BFSQueue
// Path: G:\Secure Project\WebCrawlerProject\PageCrawlQueue
// Code lines: 161, Size of file: 5.44 KB
// Creation date: 1/12/2009 3:22 PM
// Last modified: 1/12/2009 6:21 PM

// Project: PageCrawlQueue, File: BFSQueue.cs
// Namespace: PageCrawlQueue, Class: BFSQueue
// Path: G:\Secure Project\WebCrawlerProject\PageCrawlQueue, Author: Radu-Mihail
// Code lines: 130, Size of file: 3.79 KB
// Creation date: 1/11/2009 12:15 AM
// Last modified: 1/11/2009 4:18 AM

#region Using directives
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WebPage;
#endregion

namespace PageCrawlQueue
{
    class BFSQueue:IQueue
    {

        #region Private Fields
        /// <summary>
        /// _start link
        /// </summary>
        private string _startLink;
        /// <summary>
        /// _max depth
        /// </summary>
        private int _maxDepth;
        /// <summary>
        /// _max size
        /// </summary>
        private int _maxSize;
        /// <summary>
        /// _links to visit
        /// </summary>
        private List<string> _linksToVisit;

        private List<int> _levelSize;
        #endregion
        
        #region Properties
        /// <summary>
        /// Start link
        /// </summary>
        /// <returns>String</returns>
        public string StartLink
        {
            get { return _startLink; } // get
        } // StartLink

        /// <summary>
        /// Maximum depth
        /// </summary>
        /// <returns>Int</returns>
        public int MaxDepth
        {
            get { return _maxDepth; } // get
        } // MaxDepth

        /// <summary>
        /// Maximum size
        /// </summary>
        /// <returns>Int</returns>
        public int MaxSize {
            get
            {
                return _maxSize;
            } // get
        } // MaxSize

        /// <summary>
        /// Links to visit
        /// </summary>
        /// <returns>List</returns>
        public List<string> LinksToVisit { get { return _linksToVisit; } } // LinksToVisit
        #endregion

        #region Constructor

        /// <summary>
        /// Create BFS queue
        /// </summary>
        /// <param name="startLink">Start link</param>
        /// <param name="maxDepth">Maximum depth</param>
        /// <param name="maxSize">Maximum size</param>
        /// <returns>IQueue</returns>
        public BFSQueue(string startLink, int maxDepth, int maxSize)
        {
            _startLink = startLink;
            _maxDepth = maxDepth;
            _maxSize = maxSize;
            _linksToVisit = new List<string>();
            _levelSize = new List<int>();
            _linksToVisit.Add(startLink);
            _levelSize.Add(1);
        } // BFSQueue(startLink, maxDepth, maxSize)
        

        #endregion

        #region Public Methods
        /// <summary>
        /// Crawl all pages starting with the initial page in the Queue
        /// </summary>
        /// <param name="depth">Depth, -1 if you don't want to use depth</param>
        /// <returns>int new depth</returns>
        public int RunQueue(int depth)
        {
            if (_linksToVisit.Count > 0)//Check if we still have lnks to visit
            {
                if (depth <= _maxDepth)
                {
                    AbstractWebPage webPage = WebPageFactory.GetWebPage(_linksToVisit[0], _maxSize);
                    if (webPage != null)
                        if (webPage.WebPageType == WebPageContentType.TEXTHTML)
                        {
                            List<string> list = webPage.LinkList;
                            if (list != null)
                            {
                                if (depth < _maxDepth - 1)
                                {
                                    if (_levelSize.Count == 1)
                                    {
                                        _levelSize.Add(list.Count);
                                    } // if (_levelSize.Count)
                                    else _levelSize[1] += list.Count;
                                    _linksToVisit.AddRange(list);
                                } // if (depth)
                            }
                            //send parsed web page to database    
                            Database.DatabaseWork databaseConnection = new Database.DatabaseWork();
                            if(webPage.Revisit == false)
                                databaseConnection.AddPage(webPage.PageLink,  webPage.LastModifiedDate.ToLocalTime().ToString());
                            else
                                databaseConnection.UpdatePage(webPage.PageLink, webPage.LastModifiedDate.ToLocalTime().ToString());
                            databaseConnection.Dispose();                           
                        } // if if (webPage.WebPageType)
                    _linksToVisit.RemoveAt(0);//Remove the parsed web page
                    webPage = null;
                    if (depth != -1)
                    {
                        _levelSize[0]--;
                        if (_levelSize[0] < 1)
                        {
                            _levelSize.RemoveAt(0);
                            depth++;
                        }                      
                    }
                    return depth;
                    //RunQueue(depth);
                } // if (depth)
            }
            return MaxDepth;
        } // RunQueue(depth)
        #endregion


    } // class BFSQueue
} // namespace PageCrawlQueue
